import {
	ab2hex
} from '../codec/util.js';

export default {
	methods: {
		// 开启适配器
		openAdapter() {
			const that = this;

			uni.showLoading({
				title: '开启适配器...',
				mask: true
			});

			that.$store.commit('adapter/updateStatus', 1);

			uni.openBluetoothAdapter({
				success(res) {
					if (res.errMsg === 'openBluetoothAdapter:ok') {
						that.$store.commit('adapter/updateStatus', 2);
					} else {
						uni.showModal({
							title: '开启适配器失败(succ)',
							content: res.errMsg,
							showCancel: false
						});
						console.error(res);
					}
				},
				fail(err) {
					uni.showModal({
						title: '开启适配器失败(fail)',
						content: JSON.stringify(err),
						showCancel: false
					});
					console.error('openAdapter', err);
				},
				complete() {
					uni.hideLoading();
				}
			});
		},
		// 搜寻附近的蓝牙外围设备
		startDiscovery() {
			const that = this;

			uni.showLoading({
				title: '开始扫描设备...',
				mask: true
			});

			// 清空已扫描设备列表
			that.clearScanned();

			that.$store.commit('adapter/updateStatus', 3);

			uni.startBluetoothDevicesDiscovery({
				// 获取设备的uuid列表
				services: ['FE60'],
				allowDuplicatesKey: true,
				success(res) {
					if (res.errMsg === 'startBluetoothDevicesDiscovery:ok') {
						that.onDeviceFound();
					} else {
						uni.showModal({
							title: '开启扫描失败(succ)',
							content: res.errMsg,
							showCancel: false
						});
						console.error(res);
					}
				},
				fail(err) {
					uni.showModal({
						title: '开启扫描失败(fail)',
						content: JSON.stringify(err),
						showCancel: false
					});
					console.error('startDiscovery', err);
				},
				complete() {
					uni.hideLoading();
				}
			});
		},
		// 监听寻找到新设备
		onDeviceFound() {
			const that = this;

			uni.onBluetoothDeviceFound((res) => {
				that.addScanned(res.devices.filter(d => d.name || d.localName));
			});
		},
		// 创建连接
		createConnection(device, callback) {
			const that = this;

			uni.showLoading({
				title: '开始连接设备...',
				mask: true
			});

			uni.createBLEConnection({
				deviceId: device.id,
				success(res) {
					uni.hideLoading();

					if (res.errMsg === 'createBLEConnection:ok') {
						uni.showToast({
							title: '设备连接成功',
							icon: 'success'
						});

						// 日志
						that.addOprLog({
							type: 'success',
							title: '设备连接',
							content: '成功 => ' + device.name
						});

						// 保存设备信息
						uni.setStorageSync('deviceId', device.id);
						uni.setStorageSync('deviceName', device.name);

						// 同步连接状态
						that.syncConnectedStatus();

						// 添加历史列表
						that.addHistory(device);

						callback && callback();
					} else {
						uni.showModal({
							title: '连接设备失败(succ)',
							content: res.errMsg,
							showCancel: false
						});
						console.error(res);
					}
				},
				fail(err) {
					uni.hideLoading();

					uni.showModal({
						title: '连接设备失败(fail)',
						content: JSON.stringify(err),
						showCancel: false
					});
					console.error('connectDevice', err);
				},
				complete() {
					that.stopDiscovery();
				}
			});
		},
		// 设置MTU
		setMTU(deviceId, callback) {
			const that = this;

			uni.showLoading({
				title: '开始设置MTU...',
				mask: true
			});

			setTimeout(() => {
				uni.setBLEMTU({
					deviceId,
					mtu: 200,
					success(res) {
						uni.hideLoading();

						if (res.errMsg === 'setBLEMTU:ok') {
							// 日志
							that.addOprLog({
								type: 'success',
								title: '设置MTU',
								content: '成功'
							});

							callback && callback();
						} else {
							uni.showModal({
								title: '设置MTU失败(succ)',
								content: res.errMsg,
								showCancel: false
							});
							console.error(res);
						}
					},
					fail(err) {
						uni.hideLoading();

						uni.showModal({
							title: '设置MTU失败(fail)',
							content: JSON.stringify(err),
							showCancel: false
						});
						console.error('setBLEMTU', err);
					}
				});
			}, 2000);
		},
		// 获取设备服务
		getDeviceServices(deviceId) {
			const that = this;

			uni.showLoading({
				title: '获取设备服务...',
				mask: true
			});

			setTimeout(() => {
				uni.getBLEDeviceServices({
					deviceId,
					success(res) {
						uni.hideLoading();

						if (res.errMsg === 'getBLEDeviceServices:ok') {
							const services = res.services;

							let serviceId;
							for (let i = 0, len = services.length; i < len; i++) {
								if (services[i].uuid.startsWith('0000FE60') && services[i].isPrimary) {
									serviceId = services[i].uuid;
									break;
								}
							}
							if (serviceId) {
								// 保存设备服务特征值
								uni.setStorageSync('serviceId', serviceId);

								that.getDeviceCharacteristics(deviceId, serviceId);
							}
						} else {
							uni.showModal({
								title: '获取设备服务失败(succ)',
								content: res.errMsg,
								showCancel: false
							});
							console.error(res);
						}
					},
					fail(err) {
						uni.hideLoading();

						uni.showModal({
							title: '获取设备服务失败(fail)',
							content: JSON.stringify(err),
							showCancel: false
						});
						console.error('getDeviceServices', err);
					}
				});
			}, 2000);
		},
		// 获取设备特征值
		getDeviceCharacteristics(deviceId, serviceId) {
			const that = this;

			uni.showLoading({
				title: '获取服务特征值...',
				mask: true
			});

			uni.getBLEDeviceCharacteristics({
				deviceId,
				serviceId,
				success(res) {
					uni.hideLoading();

					if (res.errMsg === 'getBLEDeviceCharacteristics:ok') {
						const characteristics = res.characteristics;

						let characteristic, canNotify = false,
							canWrite = false;
						for (let i = 0, len = characteristics.length; i < len; i++) {
							characteristic = characteristics[i];

							// 可监听
							if (!canNotify && (characteristic.properties.notify || characteristic.properties
									.indicate)) {
								canNotify = true;

								// 保存设备监听特征值
								uni.setStorageSync('characteristicId.read', characteristic.uuid);

								// 启用低功耗蓝牙设备特征值变化时的 notify 功能，订阅特征值
								that.notifyCharacteristicsValueChange(deviceId, serviceId, characteristic.uuid);
							}

							// 可写
							if (!canWrite && characteristic.properties.write) {
								canWrite = true;

								// 保存设备读特征值
								uni.setStorageSync('characteristicId.write', characteristic.uuid);
							}
						}
					} else {
						uni.showModal({
							title: '获取服务特征值失败(succ)',
							content: res.errMsg,
							showCancel: false
						});
						console.error(res);
					}
				},
				fail(err) {
					uni.hideLoading();

					uni.showModal({
						title: '获取服务特征值失败(fail)',
						content: JSON.stringify(err),
						showCancel: false
					});
					console.error('getDeviceCharacteristics', err);
				}
			});
		},
		// 开启特征值变化监听
		notifyCharacteristicsValueChange(deviceId, serviceId, characteristicId) {
			const that = this;

			uni.notifyBLECharacteristicValueChange({
				deviceId,
				serviceId,
				characteristicId,
				state: true,
				success(res) {
					if (res.errMsg === 'notifyBLECharacteristicValueChange:ok') {
						// 日志
						that.addOprLog({
							type: 'success',
							title: '开启监听',
							content: '成功'
						});

						that.onCharacteristicsValueChange();
					} else {
						uni.showModal({
							title: '开启特征值监听失败(succ)',
							content: res.errMsg,
							showCancel: false
						});
						console.error(res);
					}
				},
				fail(err) {
					uni.showModal({
						title: '开启特征值监听失败(fail)',
						content: JSON.stringify(err),
						showCancel: false
					});
					console.error('notifyCharacteristicsValueChange', err);
				}
			});
		},
		// 监听特征值变化
		onCharacteristicsValueChange() {
			const that = this;

			uni.showToast({
				title: '开始数据监听',
				icon: 'success'
			});

			uni.onBLECharacteristicValueChange((res) => {
				uni.showToast({
					title: '接收到设备数据',
					icon: 'success'
				});

				// 日志
				that.addOprLog({
					type: 'info',
					title: '监听特征值',
					content: ab2hex(res.value)
				});
			});
		},
		// 写入特征值
		writeCharacteristicValue(deviceId, buffer) {
			const that = this;

			const serviceId = uni.getStorageSync('serviceId');
			const characteristicId = uni.getStorageSync('characteristicId.write');
			if (!serviceId || !characteristicId) {
				uni.showModal({
					title: '写入特征值',
					content: '请先获取服务特征值',
					showCancel: false
				});
				return;
			}

			uni.writeBLECharacteristicValue({
				deviceId,
				serviceId,
				characteristicId,
				value: buffer,
				success(res) {
					if (res.errMsg === 'writeBLECharacteristicValue:ok') {
						uni.showModal({
							title: '写入特征值成功',
							content: 'ok',
							showCancel: false
						});

						// 日志
						that.addOprLog({
							type: 'success',
							title: '写入特征值',
							content: '成功 => ' + ab2hex(buffer)
						});
					} else {
						uni.showModal({
							title: '写入特征值失败(succ)',
							content: res.errMsg,
							showCancel: false
						});

						// 日志
						that.addOprLog({
							type: 'warn',
							title: '写入特征值',
							content: '失败 => ' + JSON.stringify(res)
						});
					}
				},
				fail(err) {
					uni.showModal({
						title: '写入特征值失败(fail)',
						content: JSON.stringify(err),
						showCancel: false
					});

					// 日志
					that.addOprLog({
						type: 'warn',
						title: '写入特征值',
						content: '失败 => ' + JSON.stringify(err)
					});
				}
			});
		},
		// 断开设备连接
		disconnectDevice(deviceId, deviceName, callback) {
			const that = this;

			uni.showLoading({
				title: '开始断开设备连接...',
				mask: true
			});

			uni.closeBLEConnection({
				deviceId,
				success(res) {
					uni.hideLoading();

					if (res.errMsg === 'closeBLEConnection:ok') {
						uni.showToast({
							title: '设备已断开',
							icon: 'success'
						});
						// 日志
						that.addOprLog({
							type: 'success',
							title: '设备断开',
							content: '成功 => ' + deviceName
						});

						// 移除设备相关缓存：
						// deviceId，
						// deviceName，
						// serviceId，
						// characteristicId.read，
						// characteristicId.write
						uni.clearStorageSync();

						// 同步连接状态
						that.syncConnectedStatus();

						callback && callback();
					} else {
						uni.showModal({
							title: '断开连接失败(succ)',
							content: res.errMsg,
							showCancel: false
						});
						console.error(res);
					}
				},
				fail(err) {
					uni.hideLoading();

					uni.showModal({
						title: '断开连接失败(fail)',
						content: JSON.stringify(err),
						showCancel: false
					});
					console.error('closeBLEConnection', err);
				}
			});
		},
		// 停止搜寻附近的蓝牙外围设备
		stopDiscovery() {
			const that = this;

			uni.stopBluetoothDevicesDiscovery({
				success(res) {
					if (res.errMsg === 'stopBluetoothDevicesDiscovery:ok') {
						that.$store.commit('adapter/updateStatus', 2);
					} else {
						uni.showModal({
							title: '停止扫描失败(succ)',
							content: res.errMsg,
							showCancel: false
						});
						console.error(res);
					}
				},
				fail(err) {
					uni.showModal({
						title: '停止扫描失败(fail)',
						content: JSON.stringify(err),
						showCancel: false
					});
					console.error('stopDiscovery', err);
				}
			})
		},
		// 关闭适配器
		closeAdapter() {
			const that = this;

			// 清空已扫描设备列表
			that.clearScanned();

			uni.closeBluetoothAdapter({
				success(res) {
					if (res.errMsg === 'closeBluetoothAdapter:ok') {
						that.$store.commit('adapter/updateStatus', 0);

						// 移除设备相关缓存：
						// deviceId，
						// deviceName，
						// serviceId，
						// characteristicId.read，
						// characteristicId.write
						uni.clearStorageSync();
					} else {
						uni.showModal({
							title: '关闭适配器失败(succ)',
							content: res.errMsg,
							showCancel: false
						});
						console.error(res);
					}
				},
				fail(err) {
					uni.showModal({
						title: '关闭适配器失败(succ)',
						content: JSON.stringify(err),
						showCancel: false
					});
					console.error('closeAdapter', err);
				}
			});
		}
	}
}
